﻿using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Text;
using BepInEx;
using UnityEngine;
using Erika.Utils;
namespace Erika;

public class OnShop
{
    static bool ToUpdateGoods;

    [HarmonyPatch(typeof(Trait), "OnBarter")]
    [HarmonyPrefix]
    static bool MustSellAmmoCheck(Trait __instance)
    {
        ToUpdateGoods = false;
        Thing t = __instance.owner.things.Find("chest_merchant");
        // first time should always be true
        if (t == null)
        {
            ToUpdateGoods = true;
            return true;
        }

        if (!EClass.world.date.IsExpired(t.c_dateStockExpire))
        {
            return false;
        }


        ToUpdateGoods = true;
        return true;
    }



    [HarmonyPatch(typeof(Trait), "OnBarter")]
    [HarmonyPostfix]
    static void MustSellAmmoAddItem(Trait __instance)
    {
        if (!ToUpdateGoods)
            return;
        ToUpdateGoods = false;

        Thing chest_merchant = __instance.owner.things.Find("chest_merchant");

        var type = __instance.ShopType;

        var shopLv = __instance.ShopLv;

        if (chest_merchant.things.Count > 32)
        {
            if (type == ShopType.Weapon || type == ShopType.Blackmarket || type == ShopType.Exotic)
            {
                chest_merchant.things.DestroyAll((t) =>
                {
                    return t.rarity >= Rarity.Superior;
                });
            }
        }

        var affinity = 0;
        if (__instance.owner.isChara)
        {
            affinity = (__instance.owner as Chara)._affinity;
        }

        switch (type)
        {
            case ShopType.Weapon:
                SpawnCheapAmmo();
                FromFilter("shop_weapon", EClass.rnd(shopLv * 3 + 15) < shopLv ? Rarity.Mythical : (EClass.rnd(shopLv * 4 + 20) < shopLv * 2 ? Rarity.Legendary : Rarity.Superior));
                if (shopLv > 55)
                    FromFilter("shop_weapon", EClass.rnd(shopLv * 2 + 15) < shopLv ? Rarity.Mythical : Rarity.Legendary);

                if (affinity > 100)
                    FromFilter("shop_weapon", Rarity.Artifact);
                CreateRangedWeapon(EClass.rnd(shopLv * 3 + 15) < shopLv ? Rarity.Mythical : (EClass.rnd(shopLv * 4 + 20) < shopLv * 2 ? Rarity.Legendary : Rarity.Superior));
                break;
            case ShopType.Blackmarket:
                CreateRangedWeapon(EClass.rnd(shopLv * 2 + 15) < shopLv ? Rarity.Mythical : Rarity.Legendary);
                FromFilter("shop_blackmarket", EClass.rnd(shopLv * 2 + 15) < shopLv ? Rarity.Mythical : Rarity.Legendary);
                if (shopLv > 55)
                    FromFilter("shop_blackmarket", EClass.rnd(shopLv * 2 + 15) < shopLv ? Rarity.Mythical : Rarity.Legendary);

                if (affinity > 100)
                    FromFilter("shop_blackmarket", Rarity.Artifact);

                break;
            case ShopType.Exotic:
                FromFilter("shop_blackmarket", EClass.rnd(shopLv * 2 + 15) < shopLv ? Rarity.Mythical : Rarity.Legendary);
                FromFilter("shop_blackmarket", EClass.rnd(shopLv * 2 + 15) < shopLv ? Rarity.Mythical : Rarity.Legendary);
                if (shopLv > 55)
                    FromFilter("shop_blackmarket", EClass.rnd(shopLv * 2 + 15) < shopLv ? Rarity.Mythical : Rarity.Legendary);
                break;
            case ShopType.Guild:
                break;
            case ShopType.General:
            case ShopType.GeneralExotic:
                if (ErikaRand.Next(0, 100) < 50)
                    AddThing("bullet", shopLv, shopLv * 5 * ErikaRand.Next(5, 10) / ErikaRand.Next(1, 3));
                if (ErikaRand.Next(0, 100) < 30)
                    AddThing("bullet_energy", shopLv, shopLv * 5 * ErikaRand.Next(5, 10) / ErikaRand.Next(1, 3));
                if (ErikaRand.Next(0, 100) < 50)
                    AddThing("quarrel", shopLv, shopLv * 5 * ErikaRand.Next(5, 12) / ErikaRand.Next(1, 3));
                if (ErikaRand.Next(0, 100) < 30)
                    AddThing("arrow", shopLv, shopLv * 5 * ErikaRand.Next(5, 12) / ErikaRand.Next(1, 3));
                AddThing("potion", shopLv, Math.Max(shopLv * ErikaRand.Next(3, 6) / ErikaRand.Next(15, 34), 1));
                AddThing("blanket_fire", shopLv, Math.Max(ErikaRand.Next(7, 15) / ErikaRand.Next(1, 5), 3));
                AddThing("blanket_cold", shopLv, Math.Max(ErikaRand.Next(7, 15) / ErikaRand.Next(1, 5), 3));
                break;
            case ShopType.Goods:
                AddThing("potion", shopLv, Math.Max(shopLv * ErikaRand.Next(3, 6) / ErikaRand.Next(15, 34), 1));
                AddThing("potion", shopLv, Math.Max(shopLv * ErikaRand.Next(3, 6) / ErikaRand.Next(15, 34), 1));
                AddThing("potion", shopLv, Math.Max(shopLv * ErikaRand.Next(3, 6) / ErikaRand.Next(15, 34), 1));
                AddThing("lockpick", shopLv, Math.Max(ErikaRand.Next(7, 16) / ErikaRand.Next(1, 5), 5));
                break;
            case ShopType.VMachine:
                SpawnCheapAmmo();
                SpawnAmmo();
                AddThing("lockpick", shopLv, Math.Max(ErikaRand.Next(7, 16) / ErikaRand.Next(1, 5), 5));
                break;
            case ShopType.Drug:
                AddThing("potion", shopLv, Math.Max(shopLv * ErikaRand.Next(3, 10) / ErikaRand.Next(15, 34), 1));
                AddThing("potion", shopLv, Math.Max(shopLv * ErikaRand.Next(4, 11) / ErikaRand.Next(15, 34), 1));
                AddThing("potion", shopLv, Math.Max(shopLv * ErikaRand.Next(5, 12) / ErikaRand.Next(15, 34), 1));
                if (affinity > 75)
                    AddThing("water", shopLv, Math.Max(shopLv * ErikaRand.Next(5, 12) / ErikaRand.Next(15, 34), 1));

                break;
            case ShopType.Seed:
                AddRandomSeed(shopLv, Math.Max(shopLv * ErikaRand.Next(5, 7) / ErikaRand.Next(3, 17), 1));
                AddRandomSeed(shopLv, Math.Max(shopLv * ErikaRand.Next(5, 9) / ErikaRand.Next(1, 17), 2));
                AddRandomSeed(shopLv, Math.Max(shopLv * ErikaRand.Next(5, 11) / ErikaRand.Next(2, 17), 3));
                if (shopLv > 22)
                    AddRandomSeed(shopLv, Math.Max(shopLv * ErikaRand.Next(5, 11) / ErikaRand.Next(2, 17), 3));
                if (shopLv > 44)
                    AddRandomSeed(shopLv, Math.Max(shopLv * ErikaRand.Next(5, 11) / ErikaRand.Next(2, 17), 3));
                if (shopLv > 66)
                    AddRandomSeed(shopLv, Math.Max(shopLv * ErikaRand.Next(5, 11) / ErikaRand.Next(2, 17), 3));
                if (shopLv > 88)
                    AddRandomSeed(shopLv, Math.Max(shopLv * ErikaRand.Next(5, 11) / ErikaRand.Next(2, 17), 3));

                if (affinity > 75)
                    AddThing("water", shopLv, Math.Max(shopLv * ErikaRand.Next(5, 12) / ErikaRand.Next(15, 34), 1));
                break;
        }


        void AddThing(string id, int lv, int num, Rarity rarity = Rarity.Random)
        {
            CardBlueprint.SetRarity(rarity);
            var t = ThingGen.Create(id, -1, lv);
            t.SetNum(num);
            t.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(t);
        }

        void AddRandomSeed(int lv, int num, Rarity rarity = Rarity.Random)
        {
            CardBlueprint.SetRarity(rarity);
            var t = TraitSeed.MakeRandomSeed();
            t.SetNum(num);
            t.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(t);
        }

        //void AddSeed(int id ,int lv, int num, Rarity rarity = Rarity.Random)
        //{
        //    CardBlueprint.SetRarity(rarity);
        //    Thing t = ThingGen.Create("seed");
        //    t.refVal = id;
        //    t.SetNum(num);
        //    t.Identify(false, IDTSource.SuperiorIdentify);
        //    chest_merchant.AddThing(t);
        //}


        void SpawnAmmo()
        {
            switch (ErikaRand.Next(0, 4))
            {
                case 0: AddThing("bullet", shopLv, shopLv * 200 * ErikaRand.Next(1, 3)); break;
                case 1: AddThing("bullet", shopLv, shopLv * 300 * ErikaRand.Next(1, 3)); break;
                case 2: AddThing("bullet", shopLv, shopLv * 400 * ErikaRand.Next(1, 3)); break;
                case 3: AddThing("bullet", shopLv, shopLv * 500 * ErikaRand.Next(1, 3)); break;

            }
        }

        void SpawnCheapAmmo()
        {
            var cheapBullets = ThingGen.Create("bullet", -1, 1).SetNum(Math.Max(shopLv * 15 * ErikaRand.Next(5, 10) / ErikaRand.Next(1, 3), 100));
            cheapBullets.ChangeMaterial(RandomCheapMaterial());
            cheapBullets.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(cheapBullets);

            cheapBullets = ThingGen.Create("bullet_energy", -1, 1).SetNum(Math.Max(shopLv * 15 * ErikaRand.Next(5, 10) / ErikaRand.Next(1, 3), 100));
            cheapBullets.ChangeMaterial(RandomCheapMaterial());
            cheapBullets.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(cheapBullets);

            cheapBullets = ThingGen.Create("quarrel", -1, 1).SetNum(Math.Max(shopLv * 15 * ErikaRand.Next(5, 10) / ErikaRand.Next(1, 3), 100));
            cheapBullets.ChangeMaterial(RandomCheapMaterial());
            cheapBullets.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(cheapBullets);

            cheapBullets = ThingGen.Create("arrow", -1, 1).SetNum(Math.Max(shopLv * 15 * ErikaRand.Next(5, 10) / ErikaRand.Next(1, 3), 100));
            cheapBullets.ChangeMaterial(RandomCheapMaterial());
            cheapBullets.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(cheapBullets);
        }

        void FromFilter(string s, Rarity rarity = Rarity.Random)
        {
            CardBlueprint.SetRarity(rarity);
            var t = ThingGen.CreateFromFilter(s, shopLv);
            t.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(t);
        }

        void CreateRangedWeapon(Rarity rarity = Rarity.Random)
        {
            CardBlueprint.SetRarity(rarity);

            string id;
            var rnd = EClass.rnd(100);
            if (rnd <= 15)
                id = "bow";
            else if(rnd <= 30)
                id = "bow_short";
            else if (rnd < 55)
                id = "crossbow";
            else if (rnd < 75)
                id = "gun";
            else if (rnd < 90)
                id = "gun_assault";
            else
                id = "gun_rail";

            var t = ThingGen.Create(id, -1, shopLv);
            t.Identify(false, IDTSource.SuperiorIdentify);
            chest_merchant.AddThing(t);
        }

        string RandomCheapMaterial()
        {
            var rnd = EClass.rnd(100);
            if (rnd <= 20)
                return "grass";
            else if (rnd <= 40)
                return "paper";
            else if (rnd < 60)
                return "oak";
            else if (rnd < 80)
                return "sand";
            else
                return "soil";
        }

    }


}

